#[derive(FromForm)]
struct TopicType {
    topic_type: String
}

#[derive(Serialize)]
struct Topic {
    id: usize,
    movie_name: String
}

#[post("/library/get_copywrite_topic", data="<topic_type>")]
fn get_copywrite_topic(topic_type: Form<TopicType>, state: State<MySqlDriver>) -> Json<Value> {
    let mut topic_list: Vec<Topic> = Vec::new();
    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        return Json(to_value(topic_list).unwrap());
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        return Json(to_value(topic_list).unwrap());
    }

    let sql: String = format!("SELECT `id`, `movie_name` FROM `topic` WHERE `type` LIKE '%,{},%'", topic_type.topic_type.as_str());
    let rows: Vec<Row> = conn.query(sql).unwrap();
    for row in rows {
        let (id, movie_name): (usize, String) = from_row(row);
        topic_list.push(Topic {
            id: id,
            movie_name: movie_name
        });
    }
    return Json(to_value(topic_list).unwrap());
}

#[derive(FromForm)]
struct CopywriteAdd {
    requirement: String,
    topic_id: usize,
    topic_type: String,
    is_check: u8,
    user: String
}

#[allow(unused_assignments)]
#[post("/library/add_copywrite_order", data="<form>")]
fn add_copywrite_order(form: Form<CopywriteAdd>, cookies: Cookies, state: State<MySqlDriver>) -> String {
    let mut except_vec: Vec<char> = Vec::new();
    except_vec.push('\'');
    except_vec.push('"');
    except_vec.push('\\');
    let user_hostr: HoString = HoString::copy_string(form.user.clone());
    let requirement_hostr: HoString = HoString::copy_string(form.requirement.clone());
    if user_hostr.contains_char_vec(except_vec.clone(), 0) == true ||
        requirement_hostr.contains_char_vec(except_vec.clone(), 0) == true {
        return "fail:表单值不能包含引号和斜杠".to_string();
    }
    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        return "fail:无法建立数据库连接".to_string();
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        return "fail:无法获取数据库连接".to_string();
    }

    let mut sql: String = String::new();
    let user_info: UserInfo = get_cookies(&cookies);
    let user_id: usize = user_info.id;
    let is_super: bool = is_superadmin(user_id, &state);
    let mut uid: usize = user_id;
    if is_super && form.is_check == 1 {
        sql = format!("SELECT `id` FROM `user` WHERE `account` = '{}' LIMIT 1", form.user.as_str());
        let id_op: Option<Row> = conn.query_first(sql.clone()).unwrap();
        if let Some(id_row) = id_op {
            let _uid: usize = from_row(id_row);
            uid = _uid;
        }
    }
    sql = format!("SELECT `tg`.`id` FROM `tag_group` AS `tg` INNER JOIN `group_topic` AS `gt` ON `gt`.`group_id` = `tg`.`id` INNER JOIN `topic` AS `t` ON `gt`.`topic_id` = `t`.`id` WHERE `t`.`type` LIKE '%,{},%' AND `gt`.`status` = 0 ORDER BY `tg`.`id` ASC", form.topic_type.as_str());
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut min: i32 = -1;
    let mut gid: i32 = -1;
    for row in rows {
        let _gid: usize = from_row(row);
        sql = format!("SELECT COUNT(`clip_o`.`id`) AS `count` FROM `clip_order` AS `clip_o` WHERE `clip_o`.`group_id` = {} AND (`clip_o`.`status` = 3 OR `clip_o`.`status` = 4)", _gid);
        let count_row: Row = conn.query_first(sql.clone()).unwrap().unwrap();
        let count: usize = from_row(count_row);
        if min == -1 || min > count as i32 {
            min = count as i32;
            gid = _gid as i32;
            if min == 0 {
                break;
            }
        }
    }
    if gid == -1 {
        return "fail:未查询到空闲小组".to_string();
    }

    sql = "INSERT INTO `copywrite_order`(`topic_id`, `title`, `requirement`, `status`, `sender_id`, `is_lock`, `group_id`, `word_file`, `refuse_reason`) VALUES(:topic_id, '', :requirement, 0, :user_id, 0, :gid, '', '')".to_string();
    let exec_result: Result<(), mysql::Error> = conn.exec_drop(sql.clone(), params!{
        "topic_id" => form.topic_id,
        "requirement" => form.requirement.clone(),
        "user_id" => uid,
        "gid" => gid
    });
    if let Ok(_) = exec_result {
        sql = "UPDATE `group_topic` SET `status` = 1 WHERE `group_id` = :gid AND `topic_id` = :topic_id".to_string();
        let _: Result<(), mysql::Error> = conn.exec_drop(sql.clone(), params!{
            "gid" => gid,
            "topic_id" => form.topic_id
        });
        sql = format!("SELECT `id` FROM `group_topic` WHERE `group_id` = {} AND `topic_id` = {} ORDER BY `id` DESC LIMIT 1", gid, form.topic_id);
        let row_op: Option<Row> = conn.query_first(sql.clone()).unwrap();
        if let Some(row) = row_op {
            let gt_id: usize = from_row(row);
            return format!("success:{}", gt_id);
        } else {
            return "fail:无法获取选题ID".to_string();
        }
    } else {
        return "fail:订单创建失败".to_string();
    }
}

#[get("/copywrite_add")]
fn copywrite_add(cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);
    let user_info: UserInfo = get_cookies(&cookies);
    let user_id: usize = user_info.id;
    let is_super: bool = is_superadmin(user_id, &state);

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "order-mod".to_string(), 
        "order-mod-menu-open".to_string(), 
        "copywrite-order-list".to_string(),
        "用户后台 - 添加文案订单".to_string(), 
        "添加文案订单".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }

    let mut point_user_tpl: String = String::new();
    if is_super {
        point_user_tpl.push_str("<div class=\"form-group\">\
                                    <label for=\"user\">指定下单用户</label>\
                                    <div class=\"input-group\">\
                                        <input type=\"text\" class=\"form-control\" placeholder=\"请填写账号并检查是否存在\" id=\"user\">\
                                        <div class=\"input-group-append\">\
                                            <button class=\"btn btn-outline-secondary\" type=\"button\" onclick=\"check_user()\">检查</button>\
                                        </div>\
                                    </div>\
                                </div>");
    }

    let mut type_button_list: String = String::new();
    let mut type_exist: Vec<String> = Vec::new();
    let sql: String = "SELECT `id`, `type` FROM `topic`".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    for row in rows {
        let (id, topic_type): (usize, String) = from_row(row);
        let type_hostr: HoString = HoString::copy_string(topic_type);
        let v_type_list: Vec<HoString> = type_hostr.split_bytes(",".as_bytes());
        for type_item in v_type_list {
            if type_item.compare_str("") == false && type_exist.contains(&type_item.to_string()) == false {
                type_exist.push(type_item.to_string());
                type_button_list.push_str(format!("<button type=\"button\" class=\"list-group-item list-group-item-action\" id=\"type{}\" onclick=\"active_type({}, '{}')\">{}</button>", id, id, type_item.to_str(), type_item.to_str()).as_str());
            }
        }
    }

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    src_vec.push("{header}".as_bytes());
    src_vec.push("{point_user_tpl}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{type_buttons}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(point_user_tpl.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    replace_vec.push(type_button_list.as_bytes());
    let footer_string: String = get_footer();
    replace_vec.push(footer_string.as_bytes());

    let mut page_str: HoString = HoFile::read_file_bytes("web/add_copywrite_order.html");
    page_str = page_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = page_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

#[derive(FromForm)]
struct CopywriteUpdate {
    id: usize,
    is_check: u8,
    requirement: String,
    topic_id: usize,
    topic_type: String
}

#[allow(unused_assignments)]
#[post("/library/update_copywrite", data="<form>")]
fn update_copywrite(form: Form<CopywriteUpdate>, cookies: Cookies, state: State<MySqlDriver>) -> String {
    let mut except_vec: Vec<char> = Vec::new();
    except_vec.push('\'');
    except_vec.push('"');
    except_vec.push('\\');
    let topic_type_hostr: HoString = HoString::copy_string(form.topic_type.clone());
    let requirement_hostr: HoString = HoString::copy_string(form.requirement.clone());
    if topic_type_hostr.contains_char_vec(except_vec.clone(), 0) == true ||
        requirement_hostr.contains_char_vec(except_vec.clone(), 0) == true {
        return "fail:表单值不能包含引号和斜杠".to_string();
    }
    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        return "fail:无法建立数据库连接".to_string();
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        return "fail:无法获取数据库连接".to_string();
    }

    let mut sql: String = String::new();
    let user_info: UserInfo = get_cookies(&cookies);
    let user_id: usize = user_info.id;
    let is_super: bool = is_superadmin(user_id, &state);
    let mut uid: usize = user_id;
    if is_super && form.is_check == 1 {
        sql = format!("SELECT `id` FROM `user` WHERE `account` = '{}' LIMIT 1", user_info.account.as_str());
        let id_op: Option<Row> = conn.query_first(sql.clone()).unwrap();
        if let Some(id_row) = id_op {
            let _uid: usize = from_row(id_row);
            uid = _uid;
        }
    }
    sql = "UPDATE `copywrite_order` SET `topic_id` = :topic_id, `requirement` = :requirement, `sender_id` = :uid WHERE `id` = :id".to_string();
    let exec: Result<(), mysql::Error> = conn.exec_drop(sql.clone(), params!{
        "topic_id" => form.topic_id,
        "requirement" => form.requirement.clone(),
        "uid" => uid,
        "id" => form.id
    });
    if let Err(_) = exec {
        return "fail:订单更新失败".to_string();
    } else {
        return "success:".to_string();
    }
}

#[allow(unused_assignments)]
#[get("/copywrite_edit?<id>")]
fn copywrite_edit(id: usize, cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);
    let user_info: UserInfo = get_cookies(&cookies);
    let user_id: usize = user_info.id;
    let is_super: bool = is_superadmin(user_id, &state);

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "order-mod".to_string(), 
        "order-mod-menu-open".to_string(), 
        "copywrite-order-list".to_string(),
        "用户后台 - 编辑文案订单".to_string(), 
        "编辑文案订单".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }

    let mut sql: String = format!("SELECT `copy_o`.`topic_id`, `copy_o`.`sender_id`, `copy_o`.`is_lock`, `copy_o`.`requirement`, `tg`.`id` AS `topic_type_id`, `tg`.`type` FROM `copywrite_order` AS `copy_o` INNER JOIN `topic` AS `t` ON `t`.`id` = `copy_o`.`topic_id` INNER JOIN `tag_group` AS `tg` ON `tg`.`id` = `copy_o`.`group_id` WHERE `copy_o`.`id` = {} LIMIT 1", id);
    let row_op: Option<Row> = conn.query_first(sql.clone()).unwrap();
    let row: Row;
    if let Some(r) = row_op {
        row = r;
    } else {
        res.set_sized_body(Cursor::new("订单ID不存在".to_string()));
        return res;
    }
    let (array_topic_id, array_sender_id, array_is_lock, array_requirement, array_topic_type_id, array_type): (usize, usize, u8, String, usize, String) = from_row(row);

    let mut save_card: String = String::new();
    let mut requirement_item: String = String::new();
    let mut type_button_list: String = String::new();
    let mut topic_button_list: String = String::new();
    let mut type_exist: Vec<String> = Vec::new();
    if (user_id == array_sender_id || is_super) && array_is_lock == 0 {
        save_card.push_str("<div class=\"card\">\
                              <div class=\"card-header\">操作</div>\
                              <div class=\"card-body\">\
                                <button type=\"button\" class=\"btn btn-primary\" id=\"save\">保存</button>\
                              </div>\
                            </div>");
        type_button_list.push_str("<div class=\"list-group\" style=\"max-height: 300px;overflow-y: auto;\">");
        requirement_item.push_str(format!("<textarea class=\"form-control\" id=\"requirement\" aria-describedby=\"requirement\">{}</textarea>", array_requirement.as_str()).as_str());
        sql = "SELECT `id`, `type` FROM `topic`".to_string();
        let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
        for row in rows {
            let (topic_type_id, topic_type): (usize, String) = from_row(row);
            let type_hostr: HoString = HoString::copy_string(topic_type.clone());
            let v_type_list: Vec<HoString> = type_hostr.split_bytes(",".as_bytes());
            let mut active_string: String = String::new();
            for type_item in v_type_list {
                if type_item.compare_str("") == false && type_exist.contains(&type_item.to_string()) == false {
                    type_exist.push(type_item.to_string());
                    let type_item_plus: HoString = HoString::copy_string(format!(",{},", type_item.to_str()));
                    let array_type_hostr: HoString = HoString::copy_string(format!(",{},", array_type.as_str()));
                    if type_item_plus.compare_bytes(array_type_hostr.to_bytes()) {
                        active_string = String::from(" active");
                    } else {
                        active_string = String::new();
                    }
                    type_button_list.push_str(format!("<button type=\"button\" class=\"list-group-item list-group-item-action{}\" id=\"type{}\" onclick=\"active_type({}, '{}')\">{}</button>", active_string.as_str(), topic_type_id, topic_type_id, type_item.to_str(), type_item.to_str()).as_str());
                }
            }
        }
        type_button_list.push_str("</div>");
        sql = format!("SELECT `id`, `movie_name` FROM `topic` WHERE `type` LIKE '%,{},%'", array_type.as_str());
        let mut topic_active_string: String = String::new();
        let rows2: Vec<Row> = conn.query(sql).unwrap();
        for row2 in rows2 {
            let (id, movie_name): (usize, String) = from_row(row2);
            if id == array_topic_id {
                topic_active_string = String::from(" active");
            } else {
                topic_active_string = String::new();
            }
            topic_button_list.push_str(format!("<button type=\"button\" class=\"list-group-item list-group-item-action{}\" id=\"topic{}\" onclick=\"active_topic({})\">{}</button>", topic_active_string.as_str(), id, id, movie_name.as_str()).as_str());
        }
    } else {
        requirement_item.push_str(format!("<div class=\"form-control\">{}</div>", array_requirement.as_str()).as_str());
        type_button_list.push_str(format!("<div class=\"form-control\">{}</div>", array_type.as_str()).as_str());
    }

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    let id_str: String = id.to_string();
    let topic_type_id_str: String = array_topic_type_id.to_string();
    let topic_id_str: String = array_topic_id.to_string();
    let footer_string: String = get_footer();
    src_vec.push("{id}".as_bytes());
    src_vec.push("{header}".as_bytes());
    src_vec.push("{save_card}".as_bytes());
    src_vec.push("{requirement_item}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{type_buttons}".as_bytes());
    src_vec.push("{topic_buttons}".as_bytes());
    src_vec.push("{topic_type_id}".as_bytes());
    src_vec.push("{topic_type}".as_bytes());
    src_vec.push("{topic_id}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(id_str.as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(save_card.as_bytes());
    replace_vec.push(requirement_item.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    replace_vec.push(type_button_list.as_bytes());
    replace_vec.push(topic_button_list.as_bytes());
    replace_vec.push(topic_type_id_str.as_bytes());
    replace_vec.push(array_type.as_bytes());
    replace_vec.push(topic_id_str.as_bytes());
    replace_vec.push(footer_string.as_bytes());

    let mut page_str: HoString = HoFile::read_file_bytes("web/edit_copywrite_order.html");
    page_str = page_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = page_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

